其他
Go语言出现后,Java还是最佳选择吗?
阿里妹导读:随着大量新生的异步框架和支持协程的语言(如Go)的出现,在很多场景下操作系统的线程调度成为了性能的瓶颈,Java也因此被质疑是否不再适应最新的云场景了。4年前,阿里JVM团队开始自研Wisp2,将Go语言的协程能力带入到Java世界。既享受Java的丰富生态,又获得异步程序的性能,Wisp2让Java平台历久弥新。
2. Java EE的一些标准都是线程级阻塞的(比如JDBC);
3. 基于阻塞模式可以快速地开发应用。
java -XX:+UseWisp2 .... # 使用Wisp参数启动Java应用
误区1: 进内核引发上下文切换
pipe(a);
while (1) {
write(a[1], a, 1);
read(a[0], a, 1);
n += 2;
}
保存各种寄存器 切换sp(call指令会自动将pc压栈)
调用系统调用(可能需要阻塞); 系统调用确实需要阻塞,kernel需要决定下一个被执行的线程(调度); 执行上下切换。
活跃线程数约等于CPU个数 每个线程不太需要阻塞
private void writeQuery(Channel ch) {
ch.write(Unpooled.wrappedBuffer("query".getBytes())).sync();
logger.info("write finish");
}
private void writeQuery(Channel ch) {
ch.write(Unpooled.wrappedBuffer("query".getBytes()))
.addListener(f -> {
logger.info("write finish");
});
}
suspend fun Channel.aWrite(msg: Any): Int =
suspendCoroutine { cont ->
write(msg).addListener { cont.resume(0) }
}
suspend fun writeQuery(ch: Channel) {
ch.aWrite(Unpooled.wrappedBuffer("query".toByteArray()))
logger.info("write finish")
}
线程控制更加精确:举个例子,比如我们可以控制代理的客户端和后端连接都绑定在同一个netty线程,所有的操作都可以threadLocal化 没有协程的runtime和调度开销(1%左右)
对于Wisp1是这样的,接入的应用的参数以及Wisp的实现做了深度的适配。 对于Wisp2,会将所有线程转换成协程,已经无需任何适配了。
synchronized/Object.wait()将占用线程,无法充分利用CPU。
还可能产生死锁,以Wisp的经验来说是一定会产生死锁(Wisp也是后来陆续支持ObectMonitor的)。
对dubbo这样的框架不友好,栈底下几乎都带有反射。
要拿阿里Java研发岗Offer吗?先来搞定这几道题!识别下方二维码或点击文末“阅读原文”立刻看题。
你可能还喜欢
点击下方图片即可阅读
KPI过时了?为什么科技公司更偏爱OKR?
打败围棋冠军后,机器智能下一步能战胜黑客吗?
深度 | POLARDB底层逻辑是什么?
关注「阿里技术」
把握前沿技术脉搏